home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / DOCVIEW.PAK / LINEDOC.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  19.8 KB  |  845 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1993, 1995 by Borland International, All Rights Reserved
  4. //
  5. //   Implements classes TDrawDocument, TDrawView, TDrawListView
  6. //----------------------------------------------------------------------------
  7. #include <owl/pch.h>
  8. #include <owl/docmanag.h>
  9. #include <owl/filedoc.h>
  10. #include <owl/dc.h>
  11. #include <owl/inputdia.h>
  12. #include <owl/chooseco.h>
  13. #include <owl/gdiobjec.h>
  14. #include <owl/listbox.h>
  15. #include <owl/docview.h>
  16. #include <classlib/arrays.h>
  17. #include <stdio.h>
  18. #include "linedoc.rc"
  19.  
  20. typedef TArray<TPoint> TPoints;
  21. typedef TArrayIterator<TPoint> TPointsIterator;
  22.  
  23. class TLine : public TPoints {
  24.   public:
  25.     // Constructor to allow construction from a color and a pen size.
  26.     // Also serves as default constructor.
  27.     //
  28.     TLine(const TColor &color = TColor(0), int penSize = 1)
  29.       : TPoints(10, 0, 10), PenSize(penSize), Color(color) {}
  30.  
  31.     // Functions to modify and query pen attributes.
  32.     //
  33.     int QueryPenSize() const { return PenSize; }
  34.     const TColor& QueryColor() const { return Color; }
  35.     void SetPen(const TColor& newColor, int penSize = 0);
  36.     void SetPen(int penSize);
  37.     bool GetPenSize();
  38.     bool GetPenColor();
  39.  
  40.     // TLine draws itself.  Returns true if everything went OK.
  41.     //
  42.     virtual bool Draw(TDC&) const;
  43.  
  44.     // The == operator must be defined for the container class, even if unused
  45.     //
  46.     bool operator ==(const TLine& other) const { return &other == this; }
  47.     friend ostream& operator <<(ostream& os, const TLine& line);
  48.     friend istream& operator >>(istream& is, TLine& line);
  49.  
  50.   protected:
  51.     int    PenSize;
  52.     TColor Color;
  53. };
  54.  
  55. typedef TArray<TLine> TLines;
  56. typedef TArrayIterator<TLine> TLinesIterator;
  57.  
  58. class _DOCVIEWCLASS TDrawDocument : public TFileDocument {
  59.   public:
  60.     enum {
  61.       PrevProperty = TFileDocument::NextProperty-1,
  62.       LineCount,
  63.       Description,
  64.       NextProperty,
  65.     };
  66.  
  67.     enum {
  68.       UndoNone,
  69.       UndoDelete,
  70.       UndoAppend,
  71.       UndoModify
  72.     };
  73.  
  74.     TDrawDocument(TDocument* parent = 0)
  75.         : TFileDocument(parent), Lines(0), UndoLine(0), UndoState(UndoNone) {}
  76.    ~TDrawDocument() { delete Lines; delete UndoLine; }
  77.  
  78.     // Implement virtual methods of TDocument
  79.     //
  80.     bool   Open(int mode, const char far* path=0);
  81.     bool   Close();
  82.     bool   IsOpen() { return Lines != 0; }
  83.     bool   Commit(bool force = false);
  84.     bool   Revert(bool clear = false);
  85.  
  86.     int         FindProperty(const char far* name);  // return index
  87.     int         PropertyFlags(int index);
  88.     const char* PropertyName(int index);
  89.     int         PropertyCount() {return NextProperty - 1;}
  90.     int         GetProperty(int index, void far* dest, int textlen=0);
  91.  
  92.     // data access functions
  93.     //
  94.     const TLine* GetLine(unsigned int index);
  95.     int    AddLine(TLine& line);
  96.     void   DeleteLine(unsigned int index);
  97.     void   ModifyLine(TLine& line, unsigned int index);
  98.     void   Clear();
  99.     void   Undo();
  100.  
  101.   protected:
  102.     TLines* Lines;
  103.     TLine* UndoLine;
  104.     int    UndoState;
  105.     int    UndoIndex;
  106.     string FileInfo;
  107.  
  108.   DECLARE_STREAMABLE(, TDrawDocument,1);
  109. };
  110.  
  111. class _DOCVIEWCLASS TDrawView : public TWindowView
  112. {
  113.   public:
  114.     TDrawView(TDrawDocument& doc, TWindow *parent = 0);
  115.    ~TDrawView() {delete DragDC; delete Line;}
  116.     static const char far* StaticName() {return "Draw View";}
  117.     const char far* GetViewName(){return StaticName();}
  118.  
  119.   protected:
  120.     TDrawDocument* DrawDoc;  // same as Doc member, but cast to derived class
  121.     TDC *DragDC;
  122.     TPen *Pen;
  123.     TLine *Line; // To hold a single line sent or received from document
  124.  
  125.     // Message response functions
  126.     void EvLButtonDown(uint, TPoint&);
  127.     void EvRButtonDown(uint, TPoint&);
  128.     void EvMouseMove(uint, TPoint&);
  129.     void EvLButtonUp(uint, TPoint&);
  130.     void Paint(TDC&, bool, TRect&);
  131.     void CmPenSize();
  132.     void CmPenColor();
  133.     void CmClear();
  134.     void CmUndo();
  135.  
  136.     // Document notifications
  137.     bool VnCommit(bool force);
  138.     bool VnRevert(bool clear);
  139.     bool VnAppend(unsigned int index);
  140.     bool VnDelete(unsigned int index);
  141.     bool VnModify(unsigned int index);
  142.  
  143.   DECLARE_RESPONSE_TABLE(TDrawView);
  144.   DECLARE_STREAMABLE(,TDrawView,1);
  145. };
  146.  
  147. class _DOCVIEWCLASS TDrawListView : public TListBox, public TView {
  148.   public:
  149.     TDrawListView(TDrawDocument& doc, TWindow* parent = 0);
  150.    ~TDrawListView(){}
  151.     static const char far* StaticName() {return "DrawList View";}
  152.  
  153.     // Overridden virtuals from TView
  154.     //
  155.     const char far* GetViewName(){return StaticName();}
  156.     TWindow* GetWindow()  {return (TWindow*)this;}
  157.     bool     SetDocTitle(const char far* docname, int index)
  158.                           {return TListBox::SetDocTitle(docname, index); }
  159.  
  160.     // Overridden virtuals from TWindow
  161.     //
  162.     bool CanClose()   {return TListBox::CanClose() && Doc->CanClose();}
  163.     bool Create();
  164.  
  165.   protected:
  166.     TDrawDocument* DrawDoc;  // same as Doc member, but cast to derived class
  167.     void LoadData();
  168.     void FormatData(const TLine* line, unsigned int index);
  169.  
  170.     // Message response functions
  171.     void CmPenSize();
  172.     void CmPenColor();
  173.     void CmClear();
  174.     void CmUndo();
  175.     void CmDelete();
  176.  
  177.     // Document notifications
  178.     bool VnIsWindow(HWND hWnd) {return GetHandle() == hWnd;}
  179.     bool VnCommit(bool force);
  180.     bool VnRevert(bool clear);
  181.     bool VnAppend(unsigned int index);
  182.     bool VnDelete(unsigned int index);
  183.     bool VnModify(unsigned int index);
  184.  
  185.   DECLARE_RESPONSE_TABLE(TDrawListView);
  186.   DECLARE_STREAMABLE(,TDrawListView,1);
  187. };
  188.  
  189. const int vnDrawAppend = vnCustomBase+0;
  190. const int vnDrawDelete = vnCustomBase+1;
  191. const int vnDrawModify = vnCustomBase+2;
  192.  
  193. NOTIFY_SIG(vnDrawAppend, unsigned int)
  194. NOTIFY_SIG(vnDrawDelete, unsigned int)
  195. NOTIFY_SIG(vnDrawModify, unsigned int)
  196.  
  197. #define EV_VN_DRAWAPPEND  VN_DEFINE(vnDrawAppend,  VnAppend,  int)
  198. #define EV_VN_DRAWDELETE  VN_DEFINE(vnDrawDelete,  VnDelete,  int)
  199. #define EV_VN_DRAWMODIFY  VN_DEFINE(vnDrawModify,  VnModify,  int)
  200.  
  201. DEFINE_DOC_TEMPLATE_CLASS(TDrawDocument, TDrawView,   DrawTemplate);
  202. DEFINE_DOC_TEMPLATE_CLASS(TDrawDocument, TDrawListView,   DrawListTemplate);
  203. DrawTemplate drawTpl("Draw Line Files","*.pts",0,"PTS",dtAutoDelete|dtUpdateDir);
  204. DrawListTemplate drawListTpl("Line List","*.pts",0,"PTS",dtAutoDelete|dtHidden);
  205.  
  206. void TLine::SetPen(int penSize)
  207. {
  208.   if (penSize < 1)
  209.     PenSize = 1;
  210.   else
  211.     PenSize = penSize;
  212. }
  213.  
  214. void TLine::SetPen(const TColor& newColor, int penSize)
  215. {
  216.   // If penSize isn't the default (0), set PenSize to the new size.
  217.   if (penSize)
  218.     PenSize = penSize;
  219.  
  220.   Color = newColor;
  221. }
  222.  
  223. bool TLine::Draw(TDC &dc) const
  224. {
  225.   // Set pen for the dc to the values for this line
  226.   TPen pen(Color, PenSize);
  227.   dc.SelectObject(pen);
  228.  
  229.   // Iterates through the points in the line i.
  230.   TPointsIterator j(*this);
  231.   bool first = true;
  232.  
  233.   while (j) {
  234.     TPoint p = j++;
  235.  
  236.     if (!first)
  237.       dc.LineTo(p);
  238.     else {
  239.       dc.MoveTo(p);
  240.       first = false;
  241.     }
  242.   }
  243.   dc.RestorePen();
  244.   return true;
  245. }
  246.  
  247. ostream& operator <<(ostream& os, const TLine& line)
  248. {
  249.   // Write the number of points in the line
  250.   os << line.GetItemsInContainer();
  251.  
  252.   // Get and write pen attributes.
  253.   os << ' ' << line.Color << ' ' << line.PenSize;
  254.  
  255.   // Get an iterator for the array of points
  256.   TPointsIterator j(line);
  257.  
  258.   // While the iterator is valid (i.e. we haven't run out of points)
  259.   while(j)
  260.     // Write the point from the iterator and increment the array.
  261.     os << j++;
  262.   os << '\n';
  263.  
  264.   // return the stream object
  265.   return os;
  266. }
  267.  
  268. istream& operator >>(istream& is, TLine& line)
  269. {
  270.   unsigned numPoints;
  271.   is >> numPoints;
  272.  
  273.   COLORREF color;
  274.   int penSize;
  275.   is >> color >> penSize;
  276.   line.SetPen(TColor(color), penSize);
  277.  
  278.   while (numPoints--) {
  279.     TPoint point;
  280.     is >> point;
  281.     line.Add(point);
  282.   }
  283.  
  284.   // return the stream object
  285.   return is;
  286. }
  287.  
  288. bool TDrawDocument::Commit(bool force)
  289. {
  290.   if (!IsDirty() && !force)
  291.     return true;
  292.  
  293.   TOutStream* os = OutStream(ofWrite);
  294.   if (!os)
  295.     return false;
  296.  
  297.   // Write the number of lines in the figure
  298.   *os << Lines->GetItemsInContainer();
  299.  
  300.   // Append a description using a resource string
  301.   *os << ' ' << FileInfo << '\n';
  302.  
  303.   // Get an iterator for the array of lines
  304.   TLinesIterator i(*Lines);
  305.  
  306.   // While the iterator is valid (i.e. we haven't run out of lines)
  307.   while (i) {
  308.     // Copy the current line from the iterator and increment the array.
  309.     *os << i++;
  310.   }
  311.   delete os;
  312.  
  313.   SetDirty(false);
  314.   return true;
  315. }
  316.  
  317. bool TDrawDocument::Revert(bool clear)
  318. {
  319.   if (!TFileDocument::Revert(clear))
  320.     return false;
  321.   if (!clear)
  322.     Open(0);
  323.   return true;
  324. }
  325.  
  326. bool TDrawDocument::Open(int /*mode*/, const char far* path)
  327. {
  328.   char fileinfo[100];
  329.   Lines = new TLines(5, 0, 5);
  330.   if (path)
  331.     SetDocPath(path);
  332.   if (GetDocPath()) {
  333.     TInStream* is = InStream(ofRead);
  334.     if (!is)
  335.       return false;
  336.  
  337.     unsigned numLines;
  338.     *is >> numLines;
  339.     is->getline(fileinfo, sizeof(fileinfo));
  340.     while (numLines--) {
  341.       TLine line;
  342.       *is >> line;
  343.       Lines->Add(line);
  344.     }
  345.     delete is;
  346.     FileInfo = fileinfo;
  347.   } else {
  348.     FileInfo = string(*::Module,IDS_FILEINFO);
  349.   }
  350.   SetDirty(false);
  351.   UndoState = UndoNone;
  352.   return true;
  353. }
  354.  
  355. bool TDrawDocument::Close()
  356. {
  357.   delete Lines;
  358.   Lines = 0;
  359.   return true;
  360. }
  361.  
  362. const TLine* TDrawDocument::GetLine(unsigned int index)
  363. {
  364.   if (!IsOpen() && !Open(ofRead | ofWrite))
  365.     return 0;
  366.   return index < Lines->GetItemsInContainer() ? &(*Lines)[index] : 0;
  367. }
  368.  
  369. int TDrawDocument::AddLine(TLine& line)
  370. {
  371.   int index = Lines->GetItemsInContainer();
  372.   Lines->Add(line);
  373.   SetDirty(true);
  374.   NotifyViews(vnDrawAppend, index);
  375.   UndoState = UndoAppend;
  376.   return index;
  377. }
  378.  
  379. void TDrawDocument::DeleteLine(unsigned int index)
  380. {
  381.   const TLine* oldLine = GetLine(index);
  382.   if (!oldLine)
  383.     return;
  384.   delete UndoLine;
  385.   UndoLine = new TLine(*oldLine);
  386.   Lines->Detach(index);
  387.   SetDirty(true);
  388.   NotifyViews(vnDrawDelete, index);
  389.   UndoState = UndoDelete;
  390. }
  391.  
  392. void TDrawDocument::ModifyLine(TLine& line, unsigned int index)
  393. {
  394.   delete UndoLine;
  395.   UndoLine = new TLine((*Lines)[index]);
  396.   SetDirty(true);
  397.   (*Lines)[index] = line;
  398.   NotifyViews(vnDrawModify, index);
  399.   UndoState = UndoModify;
  400.   UndoIndex = index;
  401. }
  402.  
  403. void TDrawDocument::Clear()
  404. {
  405.   Lines->Flush();
  406.   NotifyViews(vnRevert, true);
  407. }
  408.  
  409. void TDrawDocument::Undo()
  410. {
  411.   switch (UndoState) {
  412.     case UndoAppend:
  413.       DeleteLine(Lines->GetItemsInContainer()-1);
  414.       return;
  415.     case UndoDelete:
  416.       AddLine(*UndoLine);
  417.       delete UndoLine;
  418.       UndoLine = 0;
  419.       return;
  420.     case UndoModify:
  421.       TLine* temp = UndoLine;
  422.       UndoLine = 0;
  423.       ModifyLine(*temp, UndoIndex);
  424.       delete temp;
  425.   }
  426. }
  427.  
  428. bool TLine::GetPenSize()
  429. {
  430.   char inputText[6];
  431.  
  432.   sprintf(inputText, "%d", PenSize);
  433.   if (TInputDialog(0, "Line Thickness",
  434.                         "Input a new thickness:",
  435.                         inputText,
  436.                         sizeof(inputText),::Module).Execute() != IDOK)
  437.     return false;
  438.   PenSize = atoi(inputText);
  439.  
  440.   if (PenSize < 1)
  441.     PenSize = 1;
  442.  
  443.   return true;
  444. }
  445.  
  446. bool TLine::GetPenColor()
  447. {
  448.   TChooseColorDialog::TData colors;
  449.   static TColor custColors[16] =
  450.   {
  451.     0x010101L, 0x101010L, 0x202020L, 0x303030L,
  452.     0x404040L, 0x505050L, 0x606060L, 0x707070L,
  453.     0x808080L, 0x909090L, 0xA0A0A0L, 0xB0B0B0L,
  454.     0xC0C0C0L, 0xD0D0D0L, 0xE0E0E0L, 0xF0F0F0L
  455.   };
  456.  
  457.   colors.Flags = CC_RGBINIT;
  458.   colors.Color = TColor(QueryColor());
  459.   colors.CustColors = custColors;
  460.   if (TChooseColorDialog(0, colors).Execute() != IDOK)
  461.     return false;
  462.   SetPen(colors.Color);
  463.   return true;
  464. }
  465.  
  466. DEFINE_RESPONSE_TABLE1(TDrawView, TWindowView)
  467.   EV_WM_LBUTTONDOWN,
  468.   EV_WM_RBUTTONDOWN,
  469.   EV_WM_MOUSEMOVE,
  470.   EV_WM_LBUTTONUP,
  471.   EV_COMMAND(CM_PENSIZE, CmPenSize),
  472.   EV_COMMAND(CM_PENCOLOR, CmPenColor),
  473.   EV_COMMAND(CM_CLEAR, CmClear),
  474.   EV_COMMAND(CM_UNDO, CmUndo),
  475.   EV_VN_COMMIT,
  476.   EV_VN_REVERT,
  477.   EV_VN_DRAWAPPEND,
  478.   EV_VN_DRAWDELETE,
  479.   EV_VN_DRAWMODIFY,
  480. END_RESPONSE_TABLE;
  481.  
  482. TDrawView::TDrawView(TDrawDocument& doc,TWindow *parent)
  483.          : TWindowView(doc,parent), DrawDoc(&doc)
  484. {
  485.   DragDC = 0;
  486.   Line = new TLine(TColor::Black, 1);
  487.   SetViewMenu(new TMenuDescr(IDM_DRAWVIEW,0,2,0,0,0,1));
  488. }
  489.  
  490. void TDrawView::EvLButtonDown(uint, TPoint& point)
  491. {
  492.   if (!DragDC) {
  493.     SetCapture();
  494.     DragDC = new TClientDC(*this);
  495.     Pen = new TPen(Line->QueryColor(), Line->QueryPenSize());
  496.     DragDC->SelectObject(*Pen);
  497.     DragDC->MoveTo(point);
  498.     Line->Add(point);
  499.   }
  500. }
  501.  
  502. void TDrawView::EvRButtonDown(uint, TPoint&)
  503. {
  504.   CmUndo();
  505. }
  506.  
  507. void TDrawView::EvMouseMove(uint, TPoint& point)
  508. {
  509.   if (DragDC) {
  510.     DragDC->LineTo(point);
  511.     Line->Add(point);
  512.   }
  513. }
  514.  
  515. void TDrawView::EvLButtonUp(uint, TPoint&)
  516. {
  517.   if (DragDC) {
  518.     ReleaseCapture();
  519.     if (Line->GetItemsInContainer() > 1)
  520.       DrawDoc->AddLine(*Line);
  521.     Line->Flush();
  522.     delete DragDC;
  523.     delete Pen;
  524.     DragDC = 0;
  525.   }
  526. }
  527.  
  528. void TDrawView::CmPenSize()
  529. {
  530.   Line->GetPenSize();
  531. }
  532.  
  533. void TDrawView::CmPenColor()
  534. {
  535.   Line->GetPenColor();
  536. }
  537.  
  538. void TDrawView::CmClear()
  539. {
  540.   DrawDoc->Clear();
  541. }
  542.  
  543. void TDrawView::CmUndo()
  544. {
  545.   DrawDoc->Undo();
  546. }
  547.  
  548. void TDrawView::Paint(TDC& dc, bool, TRect&)
  549. {
  550.   // Iterates through the array of line objects.
  551.   int i = 0;
  552.   const TLine* line;
  553.   while ((line = DrawDoc->GetLine(i++)) != 0)
  554.     line->Draw(dc);
  555. }
  556.  
  557. bool TDrawView::VnCommit(bool /*force*/)
  558. {
  559.   // nothing to do here, no data held in view
  560.   return true;
  561. }
  562.  
  563. bool TDrawView::VnRevert(bool /*clear*/)
  564. {
  565.   Invalidate();  // force full repaint
  566.   return true;
  567. }
  568.  
  569. bool TDrawView::VnAppend(unsigned int index)
  570. {
  571.   TClientDC dc(*this);
  572.   const TLine* line = DrawDoc->GetLine(index);
  573.   line->Draw(dc);
  574.   return true;
  575. }
  576.  
  577. bool TDrawView::VnModify(unsigned int /*index*/)
  578. {
  579.   Invalidate();  // force full repaint
  580.   return true;
  581. }
  582.  
  583. bool TDrawView::VnDelete(unsigned int /*index*/)
  584. {
  585.   Invalidate();  // force full repaint
  586.   return true;
  587. }
  588.  
  589. DEFINE_RESPONSE_TABLE1(TDrawListView, TListBox)
  590.   EV_COMMAND(CM_PENSIZE, CmPenSize),
  591.   EV_COMMAND(CM_PENCOLOR, CmPenColor),
  592.   EV_COMMAND(CM_CLEAR, CmClear),
  593.   EV_COMMAND(CM_UNDO, CmUndo),
  594.   EV_COMMAND(CM_DELETE, CmDelete),
  595.   EV_VN_ISWINDOW,
  596.   EV_VN_COMMIT,
  597.   EV_VN_REVERT,
  598.   EV_VN_DRAWAPPEND,
  599.   EV_VN_DRAWDELETE,
  600.   EV_VN_DRAWMODIFY,
  601. END_RESPONSE_TABLE;
  602.  
  603. TDrawListView::TDrawListView(TDrawDocument& doc,TWindow *parent)
  604.        : TView(doc), TListBox(parent, GetNextViewId(), 0,0,0,0), DrawDoc(&doc)
  605. {
  606.   Attr.Style &= ~(WS_BORDER | LBS_SORT);
  607.   Attr.Style |= LBS_NOINTEGRALHEIGHT;
  608.   Attr.AccelTable = IDA_DRAWLISTVIEW;
  609.   SetViewMenu(new TMenuDescr(IDM_DRAWLISTVIEW,0,1,0,0,0,1));
  610. }
  611.  
  612. bool TDrawListView::Create()
  613. {
  614.   TListBox::Create();
  615.   LoadData();
  616.   return true;
  617. }
  618.  
  619. void TDrawListView::LoadData()
  620. {
  621.   ClearList();
  622.   int i = 0;
  623.   const TLine* line;
  624.   while ((line = DrawDoc->GetLine(i)) != 0)
  625.     FormatData(line, i++);
  626.  
  627.   SetSelIndex(0);
  628. }
  629.  
  630. void TDrawListView::FormatData(const TLine* line, int unsigned index)
  631. {
  632.   char buf[80];
  633.   TColor color(line->QueryColor());
  634.   sprintf(buf, "Color = R%d G%d B%d, Size = %d, Points = %d",
  635.            color.Red(), color.Green(), color.Blue(),
  636.            line->QueryPenSize(), line->GetItemsInContainer());
  637.   DeleteString(index);
  638.   InsertString(buf, index);
  639.   SetSelIndex(index);
  640. }
  641.  
  642. void TDrawListView::CmPenSize()
  643. {
  644.   int index = GetSelIndex();
  645.   const TLine* line = DrawDoc->GetLine(index);
  646.   if (line) {
  647.     TLine* newline = new TLine(*line);
  648.     if (newline->GetPenSize())
  649.       DrawDoc->ModifyLine(*newline, index);
  650.     delete newline;
  651.   }
  652. }
  653.  
  654. void TDrawListView::CmPenColor()
  655. {
  656.   int index = GetSelIndex();
  657.   const TLine* line = DrawDoc->GetLine(index);
  658.   if (line) {
  659.     TLine* newline = new TLine(*line);
  660.     if (newline->GetPenColor())
  661.       DrawDoc->ModifyLine(*newline, index);
  662.     delete newline;
  663.   }
  664. }
  665.  
  666. void TDrawListView::CmClear()
  667. {
  668.   DrawDoc->Clear();
  669. }
  670.  
  671. void TDrawListView::CmUndo()
  672. {
  673.   DrawDoc->Undo();
  674. }
  675.  
  676. void TDrawListView::CmDelete()
  677. {
  678.   DrawDoc->DeleteLine(GetSelIndex());
  679. }
  680.  
  681. bool TDrawListView::VnCommit(bool /*force*/)
  682. {
  683.   return true;
  684. }
  685.  
  686. bool TDrawListView::VnRevert(bool /*clear*/)
  687. {
  688.   LoadData();
  689.   return true;
  690. }
  691.  
  692. bool TDrawListView::VnAppend(unsigned int index)
  693. {
  694.   const TLine* line = DrawDoc->GetLine(index);
  695.   FormatData(line, index);
  696.   SetSelIndex(index);
  697.   return true;
  698. }
  699.  
  700. bool TDrawListView::VnDelete(unsigned int index)
  701. {
  702.   DeleteString(index);
  703.   HandleMessage(WM_KEYDOWN,VK_DOWN); // force selection
  704.   return true;
  705. }
  706.  
  707. bool TDrawListView::VnModify(unsigned int index)
  708. {
  709.   const TLine* line = DrawDoc->GetLine(index);
  710.   FormatData(line, index);
  711.   return true;
  712. }
  713.  
  714. static char* PropNames[] = {
  715.   "Line Count",             // LineCount
  716.   "Description",             // Description
  717. };
  718.  
  719. static int PropFlags[] = {
  720.   pfGetBinary|pfGetText, // LineCount
  721.   pfGetText,             // Description
  722. };
  723.  
  724. const char*
  725. TDrawDocument::PropertyName(int index)
  726. {
  727.   if (index <= PrevProperty)
  728.     return TFileDocument::PropertyName(index);
  729.   else if (index < NextProperty)
  730.     return PropNames[index-PrevProperty-1];
  731.   else
  732.     return 0;
  733. }
  734.  
  735. int
  736. TDrawDocument::PropertyFlags(int index)
  737. {
  738.   if (index <= PrevProperty)
  739.     return TFileDocument::PropertyFlags(index);
  740.   else if (index < NextProperty)
  741.     return PropFlags[index-PrevProperty-1];
  742.   else
  743.     return 0;
  744. }
  745.  
  746. int
  747. TDrawDocument::FindProperty(const char far* name)
  748. {
  749.   for (int i=0; i < NextProperty-PrevProperty-1; i++)
  750.     if (strcmp(PropNames[i], name) == 0)
  751.       return i+PrevProperty+1;
  752.   return 0;
  753. }
  754.  
  755. int
  756. TDrawDocument::GetProperty(int prop, void far* dest, int textlen)
  757. {
  758.   if (IsOpen())
  759.     switch(prop)
  760.     {
  761.       case LineCount:
  762.       {
  763.         int count = Lines->GetItemsInContainer();
  764.         if (!textlen) {
  765.           *(int far*)dest = count;
  766.           return sizeof(int);
  767.         }
  768.         return sprintf((char*)dest, "%d", count);
  769.       }
  770.       case Description:
  771.         char* temp = new char[textlen]; // need local copy for medium model
  772.         int len = FileInfo.copy(temp, textlen);
  773.         strcpy((char*)dest, temp);
  774.         return len;
  775.     }
  776.   return TFileDocument::GetProperty(prop, dest, textlen);
  777. }
  778.  
  779. IMPLEMENT_STREAMABLE1(TDrawDocument, TFileDocument);
  780.  
  781. void*
  782. TDrawDocument::Streamer::Read(ipstream& is, uint32 /*version*/) const
  783. {
  784.   TDrawDocument* o = GetObject();
  785.   o->UndoState = UndoNone;
  786.   o->UndoLine = 0;
  787.   o->Lines = 0;
  788.   ReadBaseObject((TFileDocument*)o, is);
  789.   return o;
  790. }
  791.  
  792. void
  793. TDrawDocument::Streamer::Write(opstream& os) const
  794. {
  795.   WriteBaseObject((TFileDocument*)GetObject(), os);
  796. }
  797.  
  798. IMPLEMENT_STREAMABLE1(TDrawView, TWindowView);
  799.  
  800. void*
  801. TDrawView::Streamer::Read(ipstream& is, uint32 /*version*/) const
  802. {
  803.   TDrawView* o = GetObject();
  804.   ReadBaseObject((TWindowView*)o, is);
  805.   is >> o->DrawDoc;
  806.   int width;
  807.   COLORREF color;
  808.   is >> width >> color;
  809.   o->Line = new TLine(TColor(color), width);
  810.   o->DragDC = 0;
  811.   return o;
  812. }
  813.  
  814. void
  815. TDrawView::Streamer::Write(opstream &os) const
  816. {
  817.   TDrawView* o = GetObject();
  818.   WriteBaseObject((TWindowView*)o, os);
  819.   os << o->DrawDoc;
  820.   os << o->Line->QueryPenSize();
  821.   os << COLORREF(o->Line->QueryColor());
  822. }
  823.  
  824. IMPLEMENT_STREAMABLE2(TDrawListView, TListBox, TView);
  825.  
  826. void*
  827. TDrawListView::Streamer::Read(ipstream& is, uint32 /*version*/) const
  828. {
  829.   TDrawListView* o = GetObject();
  830.   ReadBaseObject((TListBox*)o, is);
  831.   ReadBaseObject((TView*)o, is);
  832.   is >> o->DrawDoc;
  833.   return o;
  834. }
  835.  
  836. void
  837. TDrawListView::Streamer::Write(opstream &os) const
  838. {
  839.   TDrawListView* o = GetObject();
  840.   WriteBaseObject((TListBox*)o, os);
  841.   WriteBaseObject((TView*)o, os);
  842.   os << o->DrawDoc;
  843. }
  844.  
  845.